import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Test {
        public static void main(String[] args) {
                fake_future_test();
                real_promsie();
        }

        public static void fake_future_test() {
                // 一个Future<V>接口表示一个未来可能会返回的结果，Future 不能实例化、它定义的方法有：
                // get()：获取结果（可能会等待）
                // get(long timeout, TimeUnit unit)：获取结果，但只等待指定的时间；
                // boolean cancel(boolean mayInterruptIfRunning)：取消当前任务；
                // 参数：
                // cancel(true) = 硬中断（发 interrupt）
                // cancel(false) = 软取消（不 interrupt，只阻止未开始的任务）
                // 返回值：
                // true → 撤单成功（任务被中断或本来就已完成/取消）
                // false → 撤单失败（通常因为任务已经完成或已经被取消）
                // isDone()：判断任务是否已完成。
                Callable<Integer> c1 = () -> {
                        if (Math.random() > 0.7) {
                                throw new Exception("some exception happend!");
                        } else {
                                return 233;
                        }
                };
                FutureTask<Integer> promise = new FutureTask<>(c1);
                promise.run();
                promise.cancel(true);
                try {
                        // future.get() 会阻塞当前线程直到拿到结果
                        // 1、如果callable正常返回直接拿到结果、完成任务
                        // 2、如果callable内部throw就会抛出异常、完成任务
                        var res = promise.get();
                        System.out.println("res is " + res);
                } catch (Exception e) {
                        e.printStackTrace();
                }
                System.out.println("future是否完成 " + promise.isDone());
        }

        public static void real_promsie() {
                try {
                        // Callable = 会返回结果的任务
                        // Future = 提货单（查看进度/拿结果/取消）
                        // FutureTask 继实现了 Runnable由实现了Future

                        // 1. 创建有返回值的任务（Callable接口）
                        Callable<Integer> task = () -> {
                                System.out.println("子线程开始执行任务...");
                                // 模拟耗时操作
                                Thread.sleep(2000);
                                int result = 10 * 20; // 假设这是计算结果
                                System.out.println("子线程任务执行完毕，结果为：" + result);
                                return result;
                        };

                        // 2. 将Callable包装为FutureTask（它既是Runnable又是Future）
                        FutureTask<Integer> futureTask = new FutureTask<>(task);

                        // 3. 创建单线程，传入FutureTask（因为FutureTask实现了Runnable）
                        Thread thread = new Thread(futureTask);
                        thread.start(); // 启动线程执行任务

                        // 4. 主线程可以异步执行其他操作
                        System.out.println("主线程执行其他任务...");
                        Thread.sleep(1000); // 模拟主线程工作
                        System.out.println("主线程准备获取子线程结果...");

                        // 5. 通过FutureTask获取结果（未完成则阻塞等待）
                        Integer result = futureTask.get();
                        System.out.println("主线程获取到结果：" + result);

                } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        System.out.println("线程被中断：" + e.getMessage());
                } catch (ExecutionException e) {
                        System.out.println("子线程执行出错：" + e.getCause().getMessage());
                }
        }
}